#include <ros/ros.h>
#include <std_msgs/String.h>
// 需求：
/*
    消息订阅方:
        订阅话题并打印接收到的消息
*/

// 步骤
/*
    1.包含头文件 
    2.初始化 ROS 节点:命名(唯一)
    3.实例化 ROS 句柄
    4.实例化 订阅者 对象
    5.处理订阅的消息(回调函数)
    6.设置循环调用回调函数
*/

// 回调函数参数解析：
/*
    std_msgs::String::ConstPtr
        是 ROS 中定义的一种消息类型，它属于标准消息类型之一，用于传输字符串
        std_msgs::String 只有一个字段：data，它是一个字符串
    ConstPtr
        在 ROS 中，Ptr 是指针类型，ConstPtr 是指向常量类型对象的智能指针，表示你不能通过这个指针修改其指向的对象
        std_msgs::String::ConstPtr 就是指向 std_msgs::String 类型常量对象的指针
            std_msgs::String::Ptr：指向 std_msgs::String 类型对象的普通指针，允许修改对象
            std_msgs::String::ConstPtr：指向 std_msgs::String 类型常量对象的指针，不能修改对象内容
    &
        表示引用，即传递的是对象的引用而非复制的副本
        这意味着，传递给回调函数的是指向原始数据的引用，而不是该数据的副本。这样可以提高效率，避免不必要的数据复制
*/
void doMsg(const std_msgs::String::ConstPtr& msg_p)
{
    ROS_INFO("订阅到的消息：%s", msg_p->data.c_str());
    // ROS_INFO("订阅到的消息：%s", (*msg_p).data.c_str());
    // c_str()作用
    /*
        c_str() 是一个将 std::string 转换为 C 风格字符串的成员函数
        它返回一个 const char*，使得你能够将 std::string 传递给那些期望 C 风格字符串的 API 或函数
    */
}

int main(int argc, char *argv[])
{
    setlocale(LC_ALL, "");
    // 初始化 ROS 节点
    ros::init(argc, argv, "listener_cpp");
    // 实例化 ROS 句柄
    ros::NodeHandle nh;
    // 实例化 订阅者 对象
    //泛型: 订阅的消息类型
    //参数1: 要订阅到的话题
    //参数2: 队列中最大保存的消息数，超出此阀值时，先进的先销毁(时间早的先销毁)
    //参数3：回调函数
    ros::Subscriber sub = nh.subscribe<std_msgs::String>("first_topic", 10, doMsg);
    // 处理订阅消息（回调函数）

    // 设置循环调用回调函数
    ros::spin();    // 设置循环调用回调函数
    return 0;
}

// 配置CMakeLists.txt
/*
    add_executable(文件名称
    src/文件名称.cpp
    )

    target_link_libraries(文件名称
    ${catkin_LIBRARIES}
    )
*/
